package si.wasu.drawable;

import java.util.Stack;

public class Racun {
	private String prefixRacun;
	private String infixRacun;	//za izris
	private int evaluated;
	private Stack<Double> nums=new Stack<Double>();;
	private static final String CHARACTER = "\\+|\\-|\\*|\\/";
	private static final String UNSIGNED_DOUBLE = "((\\d+\\.?\\d*)|(\\.\\d+))([Ee][-+]?\\d+)?.*?";
	private boolean isConst;
	

//	public static void main(String[] args) {
//		String s="- * / 15 - 7 + 1 1 3 + 2 + 1 1";
//		Racun r=new Racun(s, false);
//		System.out.println(r.getInfixRacun()+"="+r.evaluate());
//		System.out.println(PrefixToInfixConverter.convert(s));
//	}
	
	public Racun() {
		this("45");	//default
	}
	
	public Racun(String prefix) {
		setPrefixRacun(prefix);
		setConst(isConstant(prefix));
		
		if(prefix.equals("")){
			setInfixRacun("");
		}
		else if(isConst()) {
			setInfixRacun(prefix);
			setEvaluated(Integer.parseInt(prefix));
		}
		else {
			nums.clear();
			convertToInfix();	//nastavi tudi infix spremenljivko
			setEvaluated(evaluate());
		}
	}
	
	public boolean isConst() {
		return isConst;
	}

	public void setConst(boolean isConst) {
		this.isConst = isConst;
	}

	public void convertToInfix() {
		//pretvori prefixno v infiksno
		
		String[] infix=getPrefixRacun().split(" ");
		
		
		setInfixRacun(infix[1]+" x "+infix[2]);
//		setInfixRacun(infix[1]+" "+infix[0]+" "+infix[2]);
	}
	
	public int evaluate() {
		//vzame prefix in izracuna
		String[] ss=getPrefixRacun().split(" ");
		
		//imamo izraz
		for(int x = (ss.length - 1); x >= 0; x--) {
			//working from the end of the array forward
			if (ss[x].matches(UNSIGNED_DOUBLE)) {
				nums.push(new Double(ss[x]));
				//if the value at expArray[x] is a double, push it
			}
			if(ss[x].matches(CHARACTER)) {
				calculate(ss[x]);
				//if the value at expArray[x] is an operator, calculate
			}
		}
		
		return nums.pop().intValue();
	}
	
	public void calculate (String n) {
        double op1 = nums.pop();//top of stack is really back of expression
        double op2 = nums.pop();
        char op = n.charAt(0);//operator
        switch (op) {
            case '+':
              nums.push(op1 + op2);
              break;
            case '-':
              nums.push(op1 - op2);
              break;
            case '*':
              nums.push(op1 * op2);
              break;
            case '/':
              nums.push(op1 / op2);
              break;
        }
    }

	public String getPrefixRacun() {
		return prefixRacun;
	}

	public void setPrefixRacun(String prefixRacun) {
		this.prefixRacun = prefixRacun;
	}
	
	public String getInfixRacun() {
		return infixRacun;
	}

	public void setInfixRacun(String infixRacun) {
		this.infixRacun = infixRacun;
	}

	public int getEvaluated() {
		return evaluated;
	}

	public void setEvaluated(int evaluated) {
		this.evaluated = evaluated;
	}
	
	public static boolean isConstant(String exp) {
		return exp.split(" ").length<2;
	}

}

